<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>修勾夜店</title>
    <script src="https://www.jq22.com/jquery/jquery-1.10.2.js"></script>
    <script type="text/javascript" th:src="@{/js/decode.js}"></script>
    <style>
    </style>

</head>
<body>

<input type="hidden" id="roomid" th:value="${roomId}">
<input type="hidden" id="token" th:value="${token}">
<input type="hidden" id="url" th:value="${url}">
<!--    <div id="music"></div>-->

<div id="wutai" style="width: 100%;height: 100%;position:absolute;">
    <button onclick="javascript:createDog('test');">测试专用</button>
    <button onclick="javascript:creatDJ('test');">DJ专用</button>
    <div style="width: 100%;height: 50%">
        <img th:src="@{/img/bj.jpeg}" style="width: 100%;height: 100%">

    </div>
    <div style="width: 100%;height: 50%">
        <img th:src="@{/img/bg1.png}" style="width: 100%;height: 100%">
    </div>
    <!--        <div style="  position: absolute;left: 40%;top: 35%;">-->
    <!--            <img th:src="@{/img/dj.gif}">-->
    <!--        </div>-->
    <div style=" position: absolute;left: 42%;top: 45%;">
        <p class="dj_name" id="null" style="text-align: center;color: #00FFFF">当前DJ台虚位以待！</p>
    </div>
    <canvas id="canvas" width="1920" height="950"></canvas>
    <style>canvas {
        display: block;
        position: relative;
        zindex: 1;
        pointer-events: none;
        position: fixed;
        top: 0;
    }</style>
    <script th:src="@{/js/confetti.js}"></script>
</div>
</body>


<!--监听弹幕js-->
<script type="text/javascript">
    function createDog(uname) {
        let wutai = document.getElementById('wutai');
        let x = Math.floor((Math.random() * 100) + 1) * 18;
        let y = Math.floor((Math.random() * 100) + 1) * 4 + 490;
        let dog = Math.round(Math.random() * 3) + 1;
        let addDiv = '<div id="' + uname + '_xiugo" style="width: 150px;position:absolute;top: ' + y + 'px;left: ' + x + 'px;text-align: center;">\n' +
            '            <p id="' + uname + '_message" style="background-color: white; border-radius: 3px;text-align:center" class="message"></p>' +
            '            <p id="' + uname + '_name" style="color: azure;text-align:center">' + uname + '</p>\n' +
            '            <img id="' + uname + '_image" src="/img/gif/dog' + dog + '.gif" style="width:50%">\n' +
            '        </div>';


        wutai.insertAdjacentHTML('beforeend', addDiv);
    }

    function creatDJ(uname) {
        let xiugou = document.getElementById(uname + '_xiugo');
        xiugou.style.left = "850px";
        xiugou.style.top = "300px";
        let name = document.getElementById(uname + '_name');
        name.style.color = "#FF0000";
        let dj = document.getElementsByClassName('dj_name');
        dj[0].id = uname;
        dj[0].innerHTML = '当前DJ是：' + uname + '，让我们嗨起来！';
        setTimeout(function (){
            moveTo(uname, 850, 600);
            dj[0].id = null;
            dj[0].innerHTML = 'DJ台虚位以待！';
        },1000*60*3);
    }

    let token = document.getElementById("token").value;
    let url = document.getElementById("url").value;
    let roomid = document.getElementById("roomid").value;

    var eventTarget = new EventTarget();

    //事件注册
    function on(eventType, callback) {
        eventTarget.addEventListener(eventType, function (e) {
            callback(e.detail);
        });
    }

    //生成认证数据
    function getCertification(json) {
        let encoder = new TextEncoder();    //编码器
        let jsonView = encoder.encode(json);    //utf-8编码
        let buff = new ArrayBuffer(jsonView.byteLength + 16);    //数据包总长度：16位头部长度+bytes长度
        let view = new DataView(buff);    //新建操作视窗
        view.setUint32(0, jsonView.byteLength + 16);    //整个数据包长度
        view.setUint16(4, 16);    //头部长度
        view.setUint16(6, 1);    //协议版本
        view.setUint32(8, 7);    //类型,7为加入房间认证
        view.setUint32(12, 1);    //填1
        for (let r = 0; r < jsonView.byteLength; r++) {
            view.setUint8(16 + r, jsonView[r]);    //填入数据
        }
        return buff;
    }

    function handleMessage(blob, call) {
        let reader = new FileReader();
        reader.onload = function (e) {
            let buff = e.target.result;    //ArrayBuffer对象
            let decoder = new TextDecoder();    //解码器
            let view = new DataView(buff);    //视图
            let offset = 0;
            let packet = {};
            let result = [];
            while (offset < buff.byteLength) {    //数据提取
                let packetLen = view.getUint32(offset + 0);
                let headLen = view.getUint16(offset + 4);
                let packetVer = view.getUint16(offset + 6);
                let packetType = view.getUint32(offset + 8);
                let num = view.getUint32(12);
                if (packetVer == 3) {    //解压数据
                    let brArray = new Uint8Array(buff, offset + headLen, packetLen - headLen);
                    let BrotliDecode = makeBrotliDecode();    //生成Brotli格式解压工具的实例
                    let buffFromBr = BrotliDecode(brArray);    //返回Int8Array视图
                    let view = new DataView(buffFromBr.buffer);
                    let offset_Ver3 = 0;
                    while (offset_Ver3 < buffFromBr.byteLength) {    //解压后数据提取
                        let packetLen = view.getUint32(offset_Ver3 + 0);
                        let headLen = view.getUint16(offset_Ver3 + 4);
                        let packetVer = view.getUint16(offset_Ver3 + 6);
                        let packetType = view.getUint32(offset_Ver3 + 8);
                        let num = view.getUint32(12);
                        packet.Len = packetLen;
                        packet.HeadLen = headLen;
                        packet.Ver = packetVer;
                        packet.Type = packetType;
                        packet.Num = num;
                        let dataArray = new Uint8Array(buffFromBr.buffer, offset_Ver3 + headLen, packetLen - headLen);
                        packet.body = decoder.decode(dataArray);    //utf-8格式数据解码，获得字符串
                        result.push(JSON.stringify(packet));    //数据打包后传入数组
                        offset_Ver3 += packetLen;
                    }
                } else {
                    packet.Len = packetLen;
                    packet.HeadLen = headLen;
                    packet.Ver = packetVer;
                    packet.Type = packetType;
                    packet.Num = num;
                    let dataArray = new Uint8Array(buff, offset + headLen, packetLen - headLen);
                    if (packetType == 3) {    //获取人气值
                        packet.body = (new DataView(buff, offset + headLen, packetLen - headLen)).getUint32(0);    //若入参为dataArray.buffer，会返回整段buff的视图，而不是截取后的视图
                    } else {
                        packet.body = decoder.decode(dataArray);    //utf-8格式数据解码，获得字符串
                    }
                    result.push(JSON.stringify(packet));    //数据打包后传入数组
                }
                offset += packetLen;
            }
            call(result);    //数据后续处理
        }
        reader.readAsArrayBuffer(blob);    //读取服务器传来的数据转换为ArrayBuffer
    }

    function webSocket(room_id) {

        if ("WebSocket" in window) {
            console.log("您的浏览器支持WebSocket");
            var timer;    //心跳包定时器
            var ws = new WebSocket(url);

            //连接成功后发送认证信息和设置心跳包定时器
            ws.onopen = function (e) {
                console.log("open");
                var certification = {
                    "uid": 0,
                    "roomid": room_id,
                    "protover": 3,
                    "platform": "web",
                    "type": 2,
                    "key": token
                }
                ws.send(getCertification(JSON.stringify(certification)));
                console.log(JSON.stringify(certification))
                //发送心跳包
                timer = setInterval(function () {
                    let buff = new ArrayBuffer(16);
                    let i = new DataView(buff);
                    i.setUint32(0, 0);    //整个封包
                    i.setUint16(4, 16);    //头部
                    i.setUint16(6, 1);    //协议版本
                    i.setUint32(8, 2);    //操作码,2为心跳包
                    i.setUint32(12, 1);    //填1
                    ws.send(buff);
                }, 30000); //30秒
            }


            //连接关闭后停止心跳包定时器
            ws.onclose = function (e) {
                //当客户端收到服务端发送的关闭连接请求时，触发onclose事件
                console.log("close");
                if (timer != null) {
                    clearInterval(timer);    //停止发送心跳包
                }
                setTimeout(webSocket, 4000);    //4秒后重连，按需设置或不重连
            }


            //数据处理
            ws.onmessage = function (e) {
                //当客户端收到服务端发来的消息时，触发onmessage事件，参数e.data包含server传递过来的数据
                console.log(e.data);
                let blob = e.data;
                handleMessage(blob, function (result) {
                    //触发事件
                    for (let i = 0; i < result.length; i++) {
                        let json = JSON.parse(result[i]);
                        console.log('cmd = ' + JSON.parse(json.body).cmd);
                        console.log('type = ' + json.Type);
                        if (json.Type == 5) {
                            let event = new CustomEvent(JSON.parse(json.body).cmd, {detail: JSON.parse(json.body)});
                            eventTarget.dispatchEvent(event);
                        }
                        if (json.Type == 8) {
                            let event = new CustomEvent("Certify_Success", {detail: JSON.parse(json.body)});
                            eventTarget.dispatchEvent(event);
                        }
                        if (json.Type == 3) {
                            let event = new CustomEvent("VIEW", {detail: json.body});
                            eventTarget.dispatchEvent(event);
                        }
                    }
                });
            }


            ws.onerror = function (e) {
                //如果出现连接、处理、接收、发送数据失败的时候触发onerror事件
                console.log(e);
            }

            //认证成功事件
            on("Certify_Success", function (e) {
                let data = e;
                if (data.code == 0) {
                    console.log("Certify_Success");
                }
            })
//人气值刷新事件
            on("VIEW", function (e) {
                let data = e;
                console.log("VIEW: " + data.toString());
            })
// 超能榜进入直播间
            on("ENTRY_EFFECT", function (e) {
                let data = e;
                console.log(data.data);
                let uname = data.data.copy_writing.split("<" + "%")[1].split("%>")[0];
                let timedata = new Date(data.data.trigger_time / 1000000);
                let time = timedata.toLocaleDateString() + " " + timedata.toTimeString().split(" ")[0];
                console.log(data.cmd + " " + time + " " + uname + " 进入直播间");

            })

//进入直播间或关注直播间事件
            on("INTERACT_WORD", function (e) {
                let data = e;
                let uname = data.data.uname;
                let timedata = new Date(data.data.timestamp * 1000);
                let time = timedata.toLocaleDateString() + " " + timedata.toTimeString().split(" ")[0];
                if (data.data.msg_type == 2) {
                    console.log(time + " " + uname + " 关注直播间");
                } else {
                    console.log(data.cmd + " " + time + " " + uname + " 进入直播间");
                    createDog(uname);
                }
            })

            function createDog(uname) {
                //创建修勾
                let wutai = document.getElementById('wutai');
                let x = Math.floor((Math.random() * 100) + 1) * 18;
                let y = Math.floor((Math.random() * 100) + 1) * 4 + 490;
                let dog = Math.round(Math.random() * 3) + 1;
                let addDiv = '<div id="' + uname + '_xiugo" style="width: 150px;position:absolute;top: ' + y + 'px;left: ' + x + 'px;text-align: center;">\n' +
                    '            <p id="' + uname + '_message" style="background-color: white; border-radius: 3px;text-align:center" class="message"></p>' +
                    '            <p id="' + uname + '_name" style="color: azure;text-align:center">' + uname + '</p>\n' +
                    '            <img id="' + uname + '_image" src="/img/gif/dog' + dog + '.gif" style="width:50%">\n' +
                    '        </div>';

                wutai.insertAdjacentHTML('beforeend', addDiv);
            }


//弹幕事件
            on("DANMU_MSG", function (e) {
                let data = e;
                let uname = data.info[2][1];
                let timedata = new Date(data.info[9].ts * 1000);
                let time = timedata.toLocaleDateString() + " " + timedata.toTimeString().split(" ")[0];
                let text = data.info[1];
                console.log(data.cmd + " " + time + " " + uname + " :" + text);
                let inst = text.split(" ");
                if (text === '换修勾') {
                    resetDog(uname);
                    return;
                } else if (text === '创建') {
                    createDog(uname);
                    return;
                } else if (text === '下场') {//有问题
                    moveTo(uname, 850, 600);
                    return;
                } else if (text === '上移') {//有问题
                    moveUp(uname);
                    return;
                } else if (text === '下移') {//有问题
                    moveDown(uname);
                    return;
                } else if (text === '左移') {//有问题
                    moveLeft(uname);
                    return;
                } else if (text === '右移') {//有问题
                    moveRight(uname);
                    return;
                } else if (inst[0] === '移动到') {
                    moveTo(uname, inst[1], inst[2]);
                    return;
                } else if (inst[0] === '一起喊') {
                    if (uname === document.getElementsByClassName('dj_name')[0].id) {
                        dj_msg(inst[1]);
                        return;
                    }
                }

                //显示文字
                let msg = document.getElementById(uname + '_message');
                if (msg == null) {
                    createDog(uname);
                    msg = document.getElementById(uname + '_message');
                }
                msg.innerText = text;
                msg.style.visibility = 'visible';
                setTimeout(function () {
                    f(uname);
                }, 3000);
            })

            function f(e) {
                let msg = document.getElementById(e + '_message');
                msg.style.visibility = 'hidden';
            }

            function resetDog(uname) {
                let img = document.getElementById(uname + '_image');
                let dog = Math.round(Math.random() * 3) + 1;
                img.src = '/img/gif/dog' + dog + '.gif';
            }

            function bigDog(uname) {
                let img = document.getElementById(uname + '_image');
                img.style.width = '70%';
                //style="width: 25%;position:absolute;top: '+y+'%;left: '+x+'%;text-align: center;"
            }

            function smallDog(uname) {
                let img = document.getElementById(uname + '_image');
                img.style.width = '50%';
            }

            // 向上
            function moveUp(uname) {
                let xiugou = document.getElementById(uname + '_xiugo');
                if (parseInt(xiugou.style.top.replace("px", "")) < 450) return
                var up = 10;
                var timer = setInterval(() => {
                    if (!up) {
                        clearInterval(timer);
                        up = 10;
                    }
                    up--;
                    xiugou.style.top = parseInt(xiugou.style.top.replace("px", "")) - up + "px"
                }, 100)
            }

            // 向下
            function moveDown(uname) {
                let xiugou = document.getElementById(uname + '_xiugo');
                if (parseInt(xiugou.style.top.replace("px", "")) > 1000) return
                var up = 10;
                var timer = setInterval(() => {
                    if (!up) {
                        clearInterval(timer);
                        up = 10;
                    }
                    up--;
                    xiugou.style.top = parseInt(xiugou.style.top.replace("px", "")) + up + "px"
                }, 100)
            }

            // 向左
            function moveLeft(uname) {
                let xiugou = document.getElementById(uname + '_xiugo');
                // xgImg.className = ""
                if (parseInt(xiugou.style.left.replace("px", "")) < 0) return moveRight()
                var up = 10;
                var timer = setInterval(() => {
                    if (!up) {
                        clearInterval(timer);
                        up = 10;
                    }
                    up--;
                    xiugou.style.left = parseInt(xiugou.style.left.replace("px", "")) - up + "px"
                }, 100)
            }

            // 向右
            function moveRight(uname) {
                let xiugou = document.getElementById(uname + '_xiugo');
                // xgImg.className = "rotate"
                if (parseInt(xiugou.style.left.replace("px", "")) > 3000) {
                    xiugou.style.left = "-10px"
                    moveLeft();
                    return;
                }
                var up = 10;
                var timer = setInterval(() => {
                    if (!up) {
                        clearInterval(timer);
                        up = 10;
                    }
                    up--;
                    xiugou.style.left = parseInt(xiugou.style.left.replace("px", "")) + up + "px"
                }, 100)
            }

            function moveTo(uname, x, y) {
                let xiugou = document.getElementById(uname + '_xiugo');
                if (x > 0 && x < 3600 && y >= 400 && y < 850) {
                    xiugou.style.left = x + "px";
                    xiugou.style.top = y + "px";
                }
                return;
            }

            function creatDJ(uname) {
                var sleep = function(time) {
                    var startTime = new Date().getTime() + parseInt(time, 10);
                    while(new Date().getTime() < startTime) {}
                };
                let dj = document.getElementsByClassName('dj_name');
                console.log(dj[0].id === 'null');
                while (dj[0].id !== 'null'){
                    sleep(10000);
                }
                dj[0].id = uname;
                dj[0].innerHTML = '当前DJ是：' + uname + '，让我们嗨起来！';
                bigDog(uname);
                let xiugou = document.getElementById(uname + '_xiugo');
                xiugou.style.left = "850px";
                xiugou.style.top = "300px";
                let name = document.getElementById(uname + '_name');
                name.style.color = "#FF0000";

                setTimeout(function (){
                    moveTo(uname, 850, 600);
                    dj[0].id = 'null';
                    dj[0].innerHTML = 'DJ台虚位以待！';
                },1000*60*3);
            }

            function dj_msg(text) {
                let msg = document.getElementsByClassName('message');
                for (let i = 0; i < msg.length -1 ; i++) {
                    msg[i].innerText = text;
                    msg[i].style.visibility = 'visible';
                }

                setTimeout(function () {
                    let msg = document.getElementsByClassName('message');
                    for (let i = 0; i < msg.length -1 ; i++) {
                        msg[i].style.visibility = 'hidden';
                    }
                    ;
                }, 3000);
            }

//礼物赠送事件
            on("SEND_GIFT", function (e) {
                let data = e;
                let uname = data.data.uname;
                let gift_num = data.data.num;
                let act = data.data.action;
                let gift_name = data.data.giftName;
                let timedata = new Date(data.data.timestamp * 1000);
                let time = timedata.toLocaleDateString() + " " + timedata.toTimeString().split(" ")[0];
                console.log(data.cmd + " " + time + " " + uname + " :" + act + " " + gift_num + " " + gift_name);
                creatDJ(uname);
            })
        } else {
            console.log("您的浏览器不支持WebSocket");
        }

    }

    webSocket(parseInt(roomid))
</script>

</html>